<template>
  <el-dialog v-model="showIconDialog" title="选取图标" class="ml-dialog" :style="coreStyle">
    <header class="container-header">
      <ml-search
        placeholder="筛选 icon"
        :width="addUnit(props.searchWidth)"
        @input="onSearch"
        @clear="onSearch">
        <template #prefix>
          <svg-icon class="prefix-icon" name="tabler:search" />
        </template>
      </ml-search>
      <el-select
        v-model="iconType"
        popper-class="ml-select-popper"
        class="ml-select"
        @change="iconTypeChange">
        <el-option v-for="type in iconPrefix" :key="type" :value="type" :label="type" />
      </el-select>
    </header>
    <div v-loading="loading" class="ml-icon-box" @click="selectIcon">
      <template v-for="item in icons">
        <span class="icon" v-html="item.icon" :data-icon="item.name" />
      </template>
    </div>
    <template #footer>
      <el-pagination
        size="large"
        :page-size="props.pageSize"
        :pager-count="props.pageCount % 2 === 0 ? props.pageCount - 1 : props.pageCount"
        layout="prev, pager, next"
        :total="page.total"
        class="ml-pagination"
        @change="pageChange" />
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
defineOptions({
  name: 'ml-icon-dialog',
})

import { iconData, type iconPrefixType, iconPrefix } from '@/service'
import { addUnit } from '@/utils/style'
import { ref, type CSSProperties, computed, reactive, onMounted } from 'vue'

const showIconDialog = defineModel<boolean>({ default: false })
const props = withDefaults(
  defineProps<{
    width?: number | string
    searchWidth?: number | string
    pageSize?: number
    pageCount?: number
  }>(),
  {
    width: 400,
    searchWidth: 252,
    pageSize: 70,
    pageCount: 5,
  },
)
const $emit = defineEmits(['selectIcon'])
const coreStyle = computed<CSSProperties>(() => ({
  width: addUnit(props.width),
}))
const iconType = ref<iconPrefixType>('weui')
const page = reactive({
  index: 1,
  total: 0,
})
// 改变icon类型
async function iconTypeChange() {
  await getIcons()
}
// 选中icon
function selectIcon(e: Event) {
  const target = e.target as HTMLElement
  const closestSpan = target.closest('span')
  const icon = closestSpan?.dataset.icon
  const svg = closestSpan?.innerHTML
  // console.log('icon', icon)
  showIconDialog.value = false
  $emit('selectIcon', icon, svg)
}
// 改变页数
async function pageChange(currentPage: number, _pageSize: number) {
  page.index = currentPage
  await getIcons()
}

// 搜索
async function onSearch(value: string | null | undefined) {
  try {
    loading.value = true
    reset()
    if (!value) getIcons()
    const flag = await iconData.searchIcons(value!)
    if (flag) {
      const res = await iconData.getIconsByPage(page.index, props.pageSize)
      icons.value = res
    }
  } finally {
    loading.value = false
  }
}

const icons = ref<{ icon: string; name: string }[]>([])
const loading = ref(false)
async function getIcons() {
  try {
    loading.value = true
    const flag = await iconData.getIconNames(iconType.value)
    page.total = iconData.total
    if (flag) {
      const res = await iconData.getIconsByPage(page.index, props.pageSize)
      icons.value = res
    }
  } finally {
    loading.value = false
  }
}
function reset() {
  page.index = 1
  page.total = 0
  icons.value.length = 0
}
onMounted(() => getIcons())
defineExpose({
  init: async () => {
    reset()
    await getIcons()
  },
})
</script>
<style lang="scss" scoped>
.container-header {
  display: flex;
  justify-content: space-between;
  column-gap: 8px;
  height: 40px;
  .prefix-icon {
    width: 20px;
    height: 20px;
  }
  .ml-select {
    --el-border-radius-base: 10px;
    border-radius: 12px;
    width: 140px;
    height: 100%;
  }
}

.ml-icon-box {
  display: flex;
  align-items: center;
  align-content: flex-start;
  flex-wrap: wrap;
  gap: 8px;
  overflow: auto;
  height: 384px;
  margin: 0 -10px;
  padding-left: 10px;
  .icon {
    display: block;
    width: 36px;
    height: 36px;
    padding: 6px;
    svg {
      width: 100%;
      height: 100%;
    }
  }
}
.ml-pagination {
  width: 100%;
  display: flex;
  justify-content: center;
}
</style>
